<!DOCTYPE html>
<html>
<head>
	<title>delineator.py Mapper</title>
	<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    
    <!-- Loads all of the javascript libraries from CDNs, so the user will need an internet connection -->
    <script src="https://code.jquery.com/jquery-3.6.1.min.js" integrity="sha256-o88AwQnZB+VDvE9tvIXrMQaPlFFSUTR+nldQm1LuPXQ=" crossorigin="anonymous"></script>
    <link rel="stylesheet" type="text/css" href="https://cdn.datatables.net/1.12.1/css/jquery.dataTables.min.css"/>
    <script type="text/javascript" src="https://cdn.datatables.net/1.12.1/js/jquery.dataTables.min.js"></script>
    <script type="text/javascript" src="https://cdn.datatables.net/colreorder/1.5.6/js/dataTables.colReorder.min.js"></script>
    <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.2/dist/leaflet.css" integrity="sha256-sA+zWATbFveLLNqWO2gtiw3HL/lh1giY/Inf1BJ0z14=" crossorigin=""/>
    <script src="https://unpkg.com/leaflet@1.9.2/dist/leaflet.js" integrity="sha256-o9N1jGDZrf5tS+Ft4gbIK7mYMipq9lqpVJ91xHSyKhg=" crossorigin=""></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet-ajax/2.1.0/leaflet.ajax.min.js"></script>

    <style type="text/css">
    
        body {
            font-family: "Arial Narrow", Arial, Helvetica, sans-serif;
        }
        
        #container {
            display: flex;
            flex-direction: row;
            gap: 15px;
        }

        #left {
            overflow: auto;
            width: auto;0
        }
        
        #right{
            width:50%
        }
        
        #map { 
            height:600px; 
            border: solid gray 1px; 
        }
        
        #requested {
            font-weight: bold; 
            font-size: 120%; 
            color: #00ccff;}
            
        #snapped {
            font-weight: bold; 
            font-size: 120%; 
            color:  #ff00ff;
        }
        
        #mouselng, #mouselat { 
            border: none;
        }
        
        table td:nth-child(4), 
            td:nth-child(5), 
            td:nth-child(6),
            td:nth-child(7),
            td:nth-child(8),
            td:nth-child(9),
            td:nth-child(10),
            td:nth-child(11)
         {
            text-align: right;
        }
    </style>

</head>

<body>

<!-- TABLE -->
<div id="container">
    <div id="left">
        <table id="data_table" class="display" style="width: 100% ">
            <thead>
                <tr>
                {% for c in columns %}
                    <th>{{ c }}</th>
                {% endfor %}
                </tr>
            </thead>
            <tbody>
            {% for row in rows %}
                <tr>
                {% for k, v in row.items() %}
                    {% if k == 'id' %}
                        <td><a href="#" onclick="loadBasin('{{ v }}')">{{ v }}</a></td>
                    {% else %}
                        <td>{{ v }}</td>
                    {% endif %}
                {% endfor %}
                </tr>
            {% endfor %}
            </tbody>
        </table>

    </div>

    <!-- MAP -->
    <div id="right">
        <h3 id="map_title">Click a watershed ID in the table</h3>
        <div id="map"></div>
        <input type="checkbox" name="watershed" id="watershed" value="" checked="checked" /><label for="watershed">Watershed</label>
        <input type="checkbox" name="rivers"    id="rivers"    value="" checked="checked" /><label for="rivers">Rivers</label>
        <input type="checkbox" name="coordinates"    id="coordinates"    value="" checked="checked" /><label for="coordinates">Mouse lat, lng:</label>
        <input type="text" size="5" id="mouselat" />
        <input type="text" size="4" id="mouselng" /><br />
        <b>Outlet points:</b>: <span id="requested">o</span> Requested  <span id="snapped">o</span> Snapped to river centerline
    </div>
</div>

</body>

<script type="text/javascript">

var basinLayer = {};
var riverLayer = {};
var gage = [];
var snapped = [];
var map = {};
var currentBasin = null; 
var riversJS = {};
var basinJS = {};

// Needed by function below to format numbers correctlly
const userLocale =
  navigator.languages && navigator.languages.length
    ? navigator.languages[0]
    : navigator.language;


// Formats numbers with 3 decimal places
var myformat = new Intl.NumberFormat(userLocale, {
    minimumFractionDigits: 3
});


// For displaying the watershed boundary on the map
var basinStyle = {
    "color": "#ff0000",
    "weight": 3,
    "fillOpacity": 0.1
};


// Style for the rivers - vary width proportional to order
function styleLines(feature) {
    return {
        weight: Math.sqrt(feature.properties.order),
        color: 'blue',
        lineJoin: 'round',  //miter | round | bevel 
    };
}


// Change the data source on the map 
function loadBasin(basinID){
    if (basinID == null) {
        return false;
    }
    
    // Store the id of the current basin 
    currentBasin = basinID; 
    
    // Remove the layer that is showing (if there is one)
    try {
        map.removeLayer(basinLayer);
        map.removeLayer(riverLayer);
        map.removeLayer(gage);
        map.removeLayer(snapped);
    } catch {
        // do nothing
    }
    
    // Just to be sure
    basin = null;
    river = null;
    gage  = null;
    
    // Get the checkbox status
    var bShowWatershed = $("#watershed").is(':checked');
    var bShowRivers = $("#rivers").is(':checked');
    
    // Add the basins. We needed to put these in a JS variable. 
    // JS in the browser can't read GeoJSON from the local file system
    // due to cross-origin restriction
    if (bShowWatershed) {
        try {
            document.head.removeChild(basinJS);
        } catch{}
        basinJS = document.createElement('script');
        basinJS.onload = function () {
            basinLayer = L.geoJSON(basin, {style: basinStyle}).addTo(map);
            map.fitBounds(basinLayer.getBounds());
            // Add a marker to show the outlet
            gage = new L.CircleMarker(gage_coords,       {radius: 5, fillOpacity: 0.5, color: '#00ccff'}).addTo(map);
            snapped = new L.CircleMarker(snapped_coords, {radius: 5, fillOpacity: 0.5, color: '#ff00ff'}).addTo(map);
            
            var name = basin.features[0].properties["name"];
            var id = basin.features[0].properties["id"];
            var s = id + " - " + name;
            $("#map_title").text(s)
        };
        basinJS.src = basinID + ".js";
        document.head.appendChild(basinJS); 
    }
    
    //Add the rivers, in a JS data file
    if (bShowRivers) {
        try {
            document.head.removeChild(riversJS);
        } catch{}
        riversJS = document.createElement('script');
        riversJS.onload = function () {
            riverLayer = L.geoJSON(rivers, {style: styleLines}).addTo(map);
        };
        riversJS.src = basinID + "_rivers.js";
        try{
            document.head.appendChild(riversJS);
        } catch{}
    }
    //Since the function was called by a hyperlink, we have to return false
    //to cancel navigation. 
    return false;
}

// Scripts that run after the page is loaded
$(document).ready(function() {
    
    // 'id', 'name', 'result', 'lat', 'lng', 'lat_snap', 'lng_snap', 'snap_dist', 'area_reported', 'area_calc', 'perc_diff']
    column_defs = [
			{"type": "html"},        // id
			{"type": "str"},        // name
			{"type": "str"},        // result
			{"type": "num-fmt"},    // lat
			{"type": "num-fmt"},    // lng
			{"type": "num-fmt"},    // lat_snap
			{"type": "num-fmt"},    // lng_snap
			{"type": "num-fmt"},    // snap_dist
			{"type": "num-fmt"},    // area_reported
			{"type": "num-fmt"},    // area_calc
			{"type": "num-fmt"}    // perc_diff

    ];
    
    //Instantiate the data table
	$('#data_table').DataTable({colReorder: true, columnDefs: column_defs});
    
    // TODO: Add the data types here, based on the columns in the table.
    
    // Leaflet map layers
    let streets = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
        maxZoom: 19,
        attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors'
    });

    // Create a satellite imagery layer
    let topo = L.tileLayer('https://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
        maxZoom: 17,
        attribution: 'Map data: &copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap</a> contributors, ' +
        '<a href="http://viewfinderpanoramas.org">SRTM</a> | Map style: &copy; <a href="https://opentopomap.org">OpenTopoMap</a> ' +
        '(<a href="https://creativecommons.org/licenses/by-sa/3.0/">CC-BY-SA</a>)'
    });
    
    let satellite = L.tileLayer('https://server.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer/tile/{z}/{y}/{x}', {
        attribution: 'Tiles &copy; Esri'
    });
    
    //Instantiate the map
    map = L.map('map', {
        center: [0, 0],
        zoom: 1,
        layers: [streets]
    });

    // Add the background tiles
    let basemapControl = {
        "Street map": streets,
        "Satellite": satellite,
        "Topographic": topo
    };
    
    // Add the little basemap switcher
    L.control.layers(basemapControl).addTo(map);
    
    // Add listeners for the checkboxes
    $("#watershed").change(function(){
        if ($(this).is(':checked')) {
            bShowBasins = true; 
            loadBasin(currentBasin);
        } else {
            try {
                map.removeLayer(basinLayer);
                map.removeLayer(gage);
            } finally {}
        }
    });
    
    $("#rivers").change(function(){
        if ($(this).is(':checked')) {
            bShowRivers = true; 
            loadBasin(currentBasin);
        } else {
            try{
                map.removeLayer(riverLayer);
            } finally {}
        }
    });
    
    // Add a listener for mousemove - this will write the lat, lng, and zoom to the page
    map.on("mousemove", function(e){
        if ($("#coordinates").is(':checked')) {  
            $("#mouselat").val(myformat.format(e.latlng.lat) + ", ");
            $("#mouselng").val(myformat.format(e.latlng.lng));
        } 
    });    
    
    // When unchecked, clear coordinates
    $("#coordinates").change(function(){
        $("#mouselat").val("");
        $("#mouselng").val("");
    });
});

</script>

</html>